`include "ascon_define.v"

module `ASCON_AEAD_DE_CTRL
(
    input                                        ascon_aead_clk_i,
    input                                        ascon_aead_rst_n_i,
//与ctrl regs相连的信号
    input                      [`CTRL_REG_W-1:0] ascon_aead_ctrl_msg_block_num_i,
    input                      [`CTRL_REG_W-1:0] ascon_aead_ctrl_msg_addr_i,
    input                      [`CTRL_REG_W-1:0] ascon_aead_ctrl_aead_ctrl_sta_i,
    input                                        ascon_aead_ctrl_aead_ctrl_en_i,
    input                                        ascon_aead_ctrl_aead_ctrl_mode_i,
    input                      [`CTRL_REG_W-1:0] ascon_aead_ctrl_aead_c_addr_i,
    output                                       ascon_aead_ctrl_prot_o,
    output                                       ascon_aead_ctrl_fsm_sta_wen_o,
    output                                       ascon_aead_ctrl_fsm_en_wen_o,
    output                                       ascon_aead_ctrl_fsm_t_wen_o,
    output                     [`CTRL_REG_W-1:0] ascon_aead_ctrl_w_sta_o,
    output                     [`CTRL_REG_W-1:0] ascon_aead_ctrl_w_en_o,
//与ascon_aead_init连接
    input                                        ascon_aead_ctrl_init_vld_i,
    output                                       ascon_aead_ctrl_init_en_o,
    output                                       ascon_aead_ctrl_init_vld_o,
    output                                       ascon_aead_ctrl_init_mode_o,
//与ascon_aead_ad连接
    input                                        ascon_aead_ctrl_ad_vld_i,
    output                                       ascon_aead_ctrl_ad_vld_o,
    output                                       ascon_aead_ctrl_ad_en_o,
    output                                       ascon_aead_ctrl_ad_mode_o,
//与ascon_aead_ct连接
    input                                        ascon_aead_ctrl_ct_vld_i,
    output                                       ascon_aead_ctrl_ct_vld_o,
    output                                       ascon_aead_ctrl_ct_en_o,
    output                                       ascon_aead_ctrl_ct_mode_o,
    output                                       ascon_aead_ctrl_ct_first_o,
    output                                       ascon_aead_ctrl_ct_last_o,
//与ascon_aead_final连接
    input                                        ascon_aead_ctrl_final_vld_i,
    output                                       ascon_aead_ctrl_final_vld_o,
    output                                       ascon_aead_ctrl_final_en_o,
    output                                       ascon_aead_ctrl_final_mode_o,
//与rx buf连接
    output                   [`BUF_ADDR_W+1-1:0] ascon_aead_ctrl_rx_buf_addr_o,
//与tx buf连接
    output                                       ascon_aead_ctrl_tx_buf_en_o,
    output                                       ascon_aead_ctrl_tx_buf_wen_o,
    output                   [`BUF_ADDR_W+1-1:0] ascon_aead_ctrl_tx_buf_addr_o
);

localparam IDLE                                  = `ASCON_AEAD_CTRL_STA'b00_0000_0000_0000;
localparam AEAD_INIT                             = `ASCON_AEAD_CTRL_STA'b00_0000_0000_0001;
localparam WITE_INIT                             = `ASCON_AEAD_CTRL_STA'b00_0000_0000_0010;
localparam AEAD_AD                               = `ASCON_AEAD_CTRL_STA'b00_0000_0000_0100;
localparam WITE_AD                               = `ASCON_AEAD_CTRL_STA'b00_0000_0000_1000;
localparam FIRST_CT                              = `ASCON_AEAD_CTRL_STA'b00_0000_0001_0000;
localparam WITE_CT                               = `ASCON_AEAD_CTRL_STA'b00_0000_0010_0000;
localparam AEAD_CT                               = `ASCON_AEAD_CTRL_STA'b00_0000_0100_0000;
localparam LAST_CT                               = `ASCON_AEAD_CTRL_STA'b00_0000_1000_0000;
localparam WITE_RELOAD                           = `ASCON_AEAD_CTRL_STA'b00_0001_0000_0000;
localparam RELOAD                                = `ASCON_AEAD_CTRL_STA'b00_0010_0000_0000;
localparam AEAD_FIN                              = `ASCON_AEAD_CTRL_STA'b00_0100_0000_0000;
localparam WITE_FIN                              = `ASCON_AEAD_CTRL_STA'b00_1000_0000_0000;
localparam AEAD_DONE                             = `ASCON_AEAD_CTRL_STA'b01_0000_0000_0000;
localparam R_LAST_CT                             = `ASCON_AEAD_CTRL_STA'b10_0000_0000_0000;

localparam TX_ADDR_W                             = `BUF_ADDR_W+1;
localparam RX_ADDR_W                             = `BUF_ADDR_W+1;
/*************接口信号声明*************/

//与ctrl regs相连的信号
wire                           [`CTRL_REG_W-1:0] msg_block_num_p;
wire                           [`CTRL_REG_W-1:0] msg_addr_p;
wire                           [`CTRL_REG_W-1:0] aead_ctrl_sta_p;
wire                                             aead_ctrl_en_p;
wire                                             aead_ctrl_mode_p;
wire                           [`CTRL_REG_W-1:0] aead_c_addr_p;
reg                                              prot_p;
reg                                              fsm_sta_wen_p;
reg                                              fsm_en_wen_p;
reg                                              fsm_t_wen_p;
reg                            [`CTRL_REG_W-1:0] w_sta_p;
reg                            [`CTRL_REG_W-1:0] w_en_p;
//与ascon_aead_init连接
wire                                             init_vld_i_p;
reg                                              init_en_p;
reg                                              init_vld_o_p;
wire                                             init_mode_p;
//与ascon_aead_ad连接
wire                                             ad_vld_i_p;
reg                                              ad_vld_o_p;
reg                                              ad_en_p;
wire                                             ad_mode_p;
//与ascon_aead_ct连接
wire                                             ct_vld_i_p;
reg                                              ct_vld_o_p;
reg                                              ct_en_p;
wire                                             ct_mode_p;
reg                                              ct_first_p;
reg                                              ct_last_p;
//与ascon_aead_final连接
wire                                             fin_vld_i_p;
reg                                              fin_vld_o_p;
reg                                              fin_en_p;
wire                                             fin_mode_p;
//与rx buf连接
wire                             [RX_ADDR_W-1:0] rx_buf_addr_p;
//与tx buf连接
reg                                              tx_buf_en_p;
reg                                              tx_buf_wen_p;
wire                             [TX_ADDR_W-1:0] tx_buf_addr_p;
/*************内部信号声明*************/

reg                   [`ASCON_AEAD_CTRL_STA-1:0] n_state;
reg                   [`ASCON_AEAD_CTRL_STA-1:0] c_state;
reg                   [`ASCON_AEAD_CTRL_STA-1:0] l_state;

reg                            [`CTRL_REG_W-1:0] cur_msg_block_num;
wire                           [`CTRL_REG_W-1:0] cur_round_num_w;
reg                            [`CTRL_REG_W-1:0] cur_round_num;
reg                              [RX_ADDR_W-1:0] cur_rx_addr;
wire                           [`CTRL_REG_W-1:0] msg_addr_w;
wire                           [`CTRL_REG_W-1:0] aead_c_addr_w;
reg                              [TX_ADDR_W-1:0] cur_tx_addr;


/*************连接接口信号*************/
//与ctrl regs相连的信号
assign msg_block_num_p                 = ascon_aead_ctrl_msg_block_num_i;
assign msg_addr_p                      = ascon_aead_ctrl_msg_addr_i;
assign aead_ctrl_sta_p                 = ascon_aead_ctrl_aead_ctrl_sta_i;
assign aead_ctrl_en_p                  = ascon_aead_ctrl_aead_ctrl_en_i;
assign aead_ctrl_mode_p                = ascon_aead_ctrl_aead_ctrl_mode_i;
assign aead_c_addr_p                   = ascon_aead_ctrl_aead_c_addr_i;

assign ascon_aead_ctrl_prot_o          = prot_p;
assign ascon_aead_ctrl_fsm_sta_wen_o   = fsm_sta_wen_p;
assign ascon_aead_ctrl_fsm_en_wen_o    = fsm_en_wen_p;
assign ascon_aead_ctrl_fsm_t_wen_o     = fsm_t_wen_p;
assign ascon_aead_ctrl_w_sta_o         = w_sta_p;
assign ascon_aead_ctrl_w_en_o          = w_en_p;
//与ascon_aead_init连接
assign init_vld_i_p                    = ascon_aead_ctrl_init_vld_i;

assign ascon_aead_ctrl_init_en_o       = init_en_p;
assign ascon_aead_ctrl_init_vld_o      = init_vld_o_p;
assign ascon_aead_ctrl_init_mode_o     = init_mode_p;
//与ascon_aead_ad连接
assign ad_vld_i_p                      = ascon_aead_ctrl_ad_vld_i;
assign ascon_aead_ctrl_ad_vld_o        = ad_vld_o_p;
assign ascon_aead_ctrl_ad_en_o         = ad_en_p;
assign ascon_aead_ctrl_ad_mode_o       = ad_mode_p;
//与ascon_aead_ct连接
assign ct_vld_i_p                      = ascon_aead_ctrl_ct_vld_i;
assign ascon_aead_ctrl_ct_vld_o        = ct_vld_o_p;
assign ascon_aead_ctrl_ct_en_o         = ct_en_p;
assign ascon_aead_ctrl_ct_mode_o       = ct_mode_p;
assign ascon_aead_ctrl_ct_first_o      = ct_first_p;
assign ascon_aead_ctrl_ct_last_o       = ct_last_p;
//与ascon_aead_final连接
assign fin_vld_i_p                     = ascon_aead_ctrl_final_vld_i;
assign ascon_aead_ctrl_final_vld_o     = fin_vld_o_p;
assign ascon_aead_ctrl_final_en_o      = fin_en_p;
assign ascon_aead_ctrl_final_mode_o    = fin_mode_p;
//与rx buf连接
assign ascon_aead_ctrl_rx_buf_addr_o   = rx_buf_addr_p;
//与tx buf连接
assign ascon_aead_ctrl_tx_buf_en_o     = tx_buf_en_p;
assign ascon_aead_ctrl_tx_buf_wen_o    = tx_buf_wen_p;
assign ascon_aead_ctrl_tx_buf_addr_o   = tx_buf_addr_p;
/*************内部信号生成*************/
//内部状态机控制信号

always @(posedge ascon_aead_clk_i or negedge ascon_aead_rst_n_i)
begin : CUR_MSG_BLOCK_NUM_PROG
  if (ascon_aead_rst_n_i == 1'b0)
    cur_msg_block_num        <= `CTRL_REG_W'b0;
  else if (c_state == IDLE && n_state == AEAD_INIT)
    if (aead_ctrl_mode_p == 1'b1)
      if (msg_block_num_p <= 32'd128)
        cur_msg_block_num    <= msg_block_num_p;
      else 
        cur_msg_block_num    <= 32'd128;
    else
      if (msg_block_num_p <= 32'd64)
        cur_msg_block_num    <= msg_block_num_p;
      else 
        cur_msg_block_num    <= 32'd64;
  else if (c_state == WITE_AD && n_state == FIRST_CT)
    cur_msg_block_num        <= cur_msg_block_num - `CTRL_REG_W'b1;
  else if (c_state == FIRST_CT && n_state == WITE_CT)
    cur_msg_block_num        <= cur_msg_block_num - `CTRL_REG_W'b1;
  else if (c_state == AEAD_CT && n_state == WITE_CT)
    cur_msg_block_num        <= cur_msg_block_num - `CTRL_REG_W'b1;
  else if (c_state == WITE_RELOAD && n_state == RELOAD)
    cur_msg_block_num        <= msg_block_num_p;
  else if (c_state == RELOAD && n_state == AEAD_CT)
    cur_msg_block_num        <= cur_msg_block_num - `CTRL_REG_W'b1;
  else
    cur_msg_block_num   <= cur_msg_block_num;
end

assign cur_round_num_w  = (aead_ctrl_mode_p == 1'b1) ? (msg_block_num_p-1)>>7 : (msg_block_num_p-1)>>6;

always @(posedge ascon_aead_clk_i or negedge ascon_aead_rst_n_i)
begin : CUR_ROUND_NUM_PROG
  if (ascon_aead_rst_n_i == 1'b0)
    cur_round_num       <= `CTRL_REG_W'b0;
  else if (c_state == IDLE && n_state == AEAD_INIT)
    cur_round_num       <= cur_round_num_w;
  else if (c_state == WITE_CT && n_state == WITE_RELOAD)
    cur_round_num       <= cur_round_num - `CTRL_REG_W'b1;
  else
    cur_round_num       <= cur_round_num;
end

assign msg_addr_w       = msg_addr_p;

always @(posedge ascon_aead_clk_i or negedge ascon_aead_rst_n_i)
begin : CUR_RX_ADDR_PROG
  if (ascon_aead_rst_n_i == 1'b0)
    cur_rx_addr         <= {RX_ADDR_W{1'b0}};
  else if ((c_state == IDLE && n_state == AEAD_INIT)||
           (c_state == WITE_RELOAD && n_state == RELOAD))
    cur_rx_addr         <= msg_addr_w[RX_ADDR_W-1:0];
  else if (aead_ctrl_mode_p == 1'b0)
    if ((c_state == FIRST_CT && n_state == WITE_CT)||
        (c_state == AEAD_CT && n_state == WITE_CT))
      cur_rx_addr       <= cur_rx_addr + 2;
    else
      cur_rx_addr       <= cur_rx_addr;
  else
    if ((c_state == FIRST_CT && n_state == WITE_CT)||
        (c_state == AEAD_CT && n_state == WITE_CT))
      cur_rx_addr       <= cur_rx_addr + 1;
    else
      cur_rx_addr       <= cur_rx_addr;
end

assign aead_c_addr_w    = aead_c_addr_p;

always @(posedge ascon_aead_clk_i or negedge ascon_aead_rst_n_i)
begin : CUR_TX_ADDR_PROG
  if (ascon_aead_rst_n_i == 1'b0)
    cur_tx_addr         <= {TX_ADDR_W{1'b0}};
  else if ((c_state == IDLE && n_state == AEAD_INIT)||
           (c_state == WITE_RELOAD && n_state == RELOAD))
    cur_tx_addr         <= aead_c_addr_w[TX_ADDR_W-1:0];
  else if (aead_ctrl_mode_p == 1'b0)
    if ((c_state == FIRST_CT && n_state == WITE_CT)||
        (l_state == RELOAD && c_state == AEAD_CT)||
        (c_state == WITE_CT && n_state == AEAD_CT))
      cur_tx_addr       <= cur_tx_addr + 2;
    else
      cur_tx_addr       <= cur_tx_addr;
  else
    if ((c_state == FIRST_CT && n_state == WITE_CT)||
        (l_state == RELOAD && c_state == AEAD_CT)||
        (c_state == WITE_CT && n_state == AEAD_CT))
      cur_tx_addr       <= cur_tx_addr + 1;
    else
      cur_tx_addr       <= cur_tx_addr;
end

//与ctrl regs相连的信号
always @(*) 
begin : PROT_P_PROG
  if (c_state == WITE_RELOAD)
    prot_p              = 1'b0;
  else if (c_state != IDLE)
    prot_p              = 1'b1;
  else
    prot_p              = 1'b0;
end

always @(*)
begin : FSM_STA_WEN_P_PROG
  if (c_state == WITE_CT && n_state == WITE_RELOAD)
    fsm_sta_wen_p       = 1'b1;
  else if (c_state == AEAD_DONE && n_state == IDLE)
    fsm_sta_wen_p       = 1'b1;
  else
    fsm_sta_wen_p       = 1'b0;
end

always @(*)
begin : FSM_EN_WEN_P_PROG
  if (c_state == WITE_CT && n_state == WITE_RELOAD)
    fsm_en_wen_p        = 1'b1;
  else if (c_state == AEAD_DONE && n_state == IDLE)
    fsm_en_wen_p        = 1'b1;
  else
    fsm_en_wen_p        = 1'b0;
end

always @(*)
begin : FSM_T_WEN_P_PROG
  if (c_state == WITE_FIN && n_state == AEAD_DONE)
    fsm_t_wen_p         = 1'b1;
  else
    fsm_t_wen_p         = 1'b0;
end

always @(*)
begin : W_STA_P_PROG
  if (c_state == WITE_CT && n_state == WITE_RELOAD)
    w_sta_p             = 32'h4000_0000;
  else if (c_state == AEAD_DONE && n_state == IDLE)
    w_sta_p             = 32'h8000_0000;
  else
    w_sta_p             = 32'h0000_0000;
end

always @(*)
begin : W_EN_P_PROG
  w_en_p                = 32'h0000_0000;
end

//与ascon_aead_init连接
always @(posedge ascon_aead_clk_i or negedge ascon_aead_rst_n_i)
begin : INIT_EN_P_PROG
  if (ascon_aead_rst_n_i == 1'b0)
    init_en_p           <= 1'b0;
  else if (c_state == IDLE && n_state == AEAD_INIT)
    init_en_p           <= 1'b1;
  else if (c_state == WITE_INIT && n_state == AEAD_AD)
    init_en_p           <= 1'b0;
  else
    init_en_p           <= init_en_p;
end

always @(posedge ascon_aead_clk_i or negedge ascon_aead_rst_n_i)
begin : INIT_VLD_O_P_PROG
  if (ascon_aead_rst_n_i == 1'b0)
    init_vld_o_p        <= 1'b0;
  else if (c_state == IDLE && n_state == AEAD_INIT)
    init_vld_o_p        <= 1'b1;
  else
    init_vld_o_p        <= 1'b0;
end

assign init_mode_p      = aead_ctrl_mode_p;

//与ascon_aead_ad连接
always @(posedge ascon_aead_clk_i or negedge ascon_aead_rst_n_i)
begin : AD_VLD_O_P_PROG
  if (ascon_aead_rst_n_i == 1'b0)
    ad_vld_o_p          <= 1'b0;
  else if (c_state == WITE_INIT && n_state == AEAD_AD)
    ad_vld_o_p          <= 1'b1;
  else
    ad_vld_o_p          <= 1'b0;
end

always @(posedge ascon_aead_clk_i or negedge ascon_aead_rst_n_i)
begin :AD_EN_P_PROG
  if (ascon_aead_rst_n_i == 1'b0)
    ad_en_p             <= 1'b0;
  else if (c_state == WITE_INIT && n_state == AEAD_AD)
    ad_en_p             <= 1'b1;
  else if (c_state == WITE_AD && n_state == FIRST_CT)
    ad_en_p             <= 1'b0;
  else
    ad_en_p             <= ad_en_p;
end

assign ad_mode_p        = aead_ctrl_mode_p;

//与ascon_aead_ct连接
always @(posedge ascon_aead_clk_i or negedge ascon_aead_rst_n_i)
begin : PT_VLD_O_P_PROG
  if (ascon_aead_rst_n_i == 1'b0)
    ct_vld_o_p          <= 1'b0;
  else if (c_state == WITE_AD && n_state == FIRST_CT)
    ct_vld_o_p          <= 1'b1;
  else if (c_state == WITE_CT && n_state == WITE_RELOAD)
    ct_vld_o_p          <= 1'b1;
  else if (c_state == WITE_CT && n_state == AEAD_CT)
    ct_vld_o_p          <= 1'b1;
  else if (c_state == RELOAD && n_state == AEAD_CT)
    ct_vld_o_p          <= 1'b1;
  else
    ct_vld_o_p          <= 1'b0;
end

always @(posedge ascon_aead_clk_i or negedge ascon_aead_rst_n_i)
begin : PT_EN_P_PROG
  if (ascon_aead_rst_n_i == 1'b0)
    ct_en_p             <= 1'b0;
  else if (c_state == WITE_AD && n_state == FIRST_CT)
    ct_en_p             <= 1'b1;
  else if (c_state == WITE_CT && n_state == WITE_RELOAD)
    ct_en_p             <= 1'b1;
  else if (c_state == RELOAD && n_state == AEAD_CT)
    ct_en_p             <= 1'b1;
  else if (c_state == LAST_CT && n_state == AEAD_FIN)
    ct_en_p             <= 1'b0;
  else
    ct_en_p             <= ct_en_p;
end

always @(posedge ascon_aead_clk_i or negedge ascon_aead_rst_n_i)
begin : PT_FIRST_P_PROG
  if (ascon_aead_rst_n_i == 1'b0)
    ct_first_p          <= 1'b0;
  else if ((c_state == WITE_AD && n_state == FIRST_CT)||
           (c_state == WITE_AD && n_state == LAST_CT))
    ct_first_p          <= 1'b1;
  else
    ct_first_p          <= 1'b0;
end

always @(posedge ascon_aead_clk_i or negedge ascon_aead_rst_n_i)
begin : PT_LAST_P_PROG
  if (ascon_aead_rst_n_i == 1'b0)
    ct_last_p           <= 1'b0;
  else if ((c_state == WITE_AD && n_state == LAST_CT)||
           (c_state == R_LAST_CT && n_state == LAST_CT)||
           (c_state == WITE_CT && n_state == LAST_CT))
    ct_last_p           <= 1'b1;
  else
    ct_last_p           <= 1'b0;
end

assign ct_mode_p        = aead_ctrl_mode_p;

//与ascon_aead_final连接
always @(posedge ascon_aead_clk_i or negedge ascon_aead_rst_n_i)
begin : FIN_VLD_O_P_PROG
  if (ascon_aead_rst_n_i == 1'b0)
    fin_vld_o_p         <= 1'b0;
  else if (c_state == LAST_CT && n_state == AEAD_FIN)
    fin_vld_o_p         <= 1'b1;
  else
    fin_vld_o_p         <= 1'b0;
end

always @(posedge ascon_aead_clk_i or negedge ascon_aead_rst_n_i)
begin :FIN_EN_P_PROG
  if (ascon_aead_rst_n_i == 1'b0)
    fin_en_p            <= 1'b0;
  else if (c_state == LAST_CT && n_state == AEAD_FIN)
    fin_en_p            <= 1'b1;
  else if (c_state == WITE_FIN && n_state == AEAD_DONE)
    fin_en_p            <= 1'b0;
  else
    fin_en_p            <= fin_en_p;
end

assign fin_mode_p       = aead_ctrl_mode_p;

//与rx buf连接

assign rx_buf_addr_p    = cur_rx_addr;

//与tx buf连接
always @(*)
begin : TX_BUF_EN_P_PROG
  if ((c_state == FIRST_CT && n_state == WITE_CT)||
      (c_state == WITE_CT && n_state == AEAD_CT)||
      (c_state == WITE_CT && n_state == WITE_RELOAD)||
      (c_state == WITE_AD && n_state == LAST_CT)||
      (c_state == R_LAST_CT && n_state == LAST_CT)||
      (l_state == RELOAD && c_state == AEAD_CT)||
      (c_state == WITE_CT && n_state == LAST_CT))
    tx_buf_en_p         = 1'b1;
  else
    tx_buf_en_p         = 1'b0;
end

always @(*)
begin : TX_BUF_WEN_P_PROG
  if ((c_state == FIRST_CT && n_state == WITE_CT)||
      (c_state == WITE_CT && n_state == AEAD_CT)||
      (c_state == WITE_CT && n_state == WITE_RELOAD)||
      (c_state == WITE_AD && n_state == LAST_CT)||
      (c_state == R_LAST_CT && n_state == LAST_CT)||
      (l_state == RELOAD && c_state == AEAD_CT)||
      (c_state == WITE_CT && n_state == LAST_CT))
    tx_buf_wen_p        = 1'b1;
  else
    tx_buf_wen_p        = 1'b0;
end

assign tx_buf_addr_p    = cur_tx_addr;

/*************状态转移信号*************/
always @(posedge ascon_aead_clk_i or negedge ascon_aead_rst_n_i)
begin : C_STATE_PROG
  if (ascon_aead_rst_n_i == 1'b0)
    c_state             <= `ASCON_AEAD_CTRL_STA'b0;
  else
    c_state             <= n_state;
end

always @(posedge ascon_aead_clk_i or negedge ascon_aead_rst_n_i)
begin : L_STATE_PROG
  if (ascon_aead_rst_n_i == 1'b0)
    l_state             <= `ASCON_AEAD_CTRL_STA'b0;
  else
    l_state             <= c_state;
end

always @(*)
begin : N_STATE_PROG
  case (c_state)
    IDLE        :
      if (aead_ctrl_en_p == 1'b1)
        n_state         = AEAD_INIT;
      else
        n_state         = IDLE;
    AEAD_INIT   :
      n_state           = WITE_INIT;
    WITE_INIT   :
      if (init_vld_i_p == 1'b1)
        n_state         = AEAD_AD;
      else
        n_state         = WITE_INIT;
    AEAD_AD     :
      n_state           = WITE_AD;
    WITE_AD     :
      if (ad_vld_i_p == 1'b1)
        if (cur_msg_block_num == `CTRL_REG_W'b1 && cur_round_num == `CTRL_REG_W'b0)      //不需要进行p运算的情况
          n_state       = LAST_CT;
        else
          n_state       = FIRST_CT;
      else
        n_state         = WITE_AD;
    FIRST_CT    :
      n_state           = WITE_CT;
    WITE_CT     :
      if (ct_vld_i_p == 1'b1)
        if (cur_msg_block_num == `CTRL_REG_W'b0 && cur_round_num != `CTRL_REG_W'b0)
          n_state       = WITE_RELOAD;
        else if (cur_msg_block_num == `CTRL_REG_W'b0 && cur_round_num == `CTRL_REG_W'b0)
          n_state       = LAST_CT;
        else if (cur_msg_block_num != `CTRL_REG_W'b0)
          n_state       = AEAD_CT;
        else
          n_state       = WITE_CT;
      else
        n_state         = WITE_CT;
    AEAD_CT     :
      n_state           = WITE_CT;
    LAST_CT     :
      n_state           = AEAD_FIN;
    WITE_RELOAD :
      if (aead_ctrl_en_p == 1'b1)
        n_state         = RELOAD;
      else
        n_state         = WITE_RELOAD;
    RELOAD      :
      if (cur_msg_block_num == `CTRL_REG_W'b1 && cur_round_num == `CTRL_REG_W'b0)
        n_state         = R_LAST_CT;
      else
        n_state         = AEAD_CT;
    R_LAST_CT   :
      n_state           = LAST_CT;
    AEAD_FIN    :
      n_state           = WITE_FIN;
    WITE_FIN    :
      if (fin_vld_i_p == 1'b1)
        n_state         = AEAD_DONE;
      else
        n_state         = WITE_FIN;
    AEAD_DONE   :
      n_state           = IDLE;
    default     :
      n_state           = IDLE;
  endcase
end

endmodule
